using System;
using System.Diagnostics;
using System.IO;
using System.ServiceProcess;
using Topshelf;
using MultiTCPProxy.Services;

namespace MultiTCPProxy.Services
{
    /// <summary>
    /// Windows服务管理类，负责安装、卸载和管理Windows服务
    /// </summary>
    public static class WindowsServiceManager
    {
        private const string ServiceName = "MultiTCPProxyService";
        private const string ServiceDisplayName = "多TCP代理服务";
        private const string ServiceDescription = "管理多个TCP代理连接的Windows服务";

        /// <summary>
        /// 检查服务是否已安装
        /// </summary>
        public static bool IsServiceInstalled()
        {
            try
            {
                ServiceController[] services = ServiceController.GetServices();
                foreach (ServiceController service in services)
                {
                    if (service.ServiceName == ServiceName)
                    {
                        return true;
                    }
                }
                return false;
            }
            catch
            {
                return false;
            }
        }

        /// <summary>
        /// 检查服务是否正在运行
        /// </summary>
        public static bool IsServiceRunning()
        {
            try
            {
                ServiceController controller = new ServiceController(ServiceName);
                return controller.Status == ServiceControllerStatus.Running;
            }
            catch
            {
                return false;
            }
        }

        /// <summary>
        /// 安装Windows服务
        /// </summary>
        public static bool InstallService()
        {
            try
            {
                string exePath = Process.GetCurrentProcess().MainModule.FileName;
                string installArgs = $"install -servicename:{ServiceName} -displayname:\"{ServiceDisplayName}\" -description:\"{ServiceDescription}\"";
                
                ProcessStartInfo startInfo = new ProcessStartInfo
                {
                    FileName = exePath,
                    Arguments = installArgs,
                    Verb = "runas", // 以管理员权限运行
                    UseShellExecute = true
                };

                using (Process process = Process.Start(startInfo))
                {
                    process.WaitForExit();
                    return process.ExitCode == 0;
                }
            }
            catch (Exception ex)
            {
                Debug.WriteLine($"安装服务失败: {ex.Message}");
                return false;
            }
        }

        /// <summary>
        /// 卸载Windows服务
        /// </summary>
        public static bool UninstallService()
        {
            try
            {
                string exePath = Process.GetCurrentProcess().MainModule.FileName;
                string uninstallArgs = $"uninstall -servicename:{ServiceName}";
                
                ProcessStartInfo startInfo = new ProcessStartInfo
                {
                    FileName = exePath,
                    Arguments = uninstallArgs,
                    Verb = "runas", // 以管理员权限运行
                    UseShellExecute = true
                };

                using (Process process = Process.Start(startInfo))
                {
                    process.WaitForExit();
                    return process.ExitCode == 0;
                }
            }
            catch (Exception ex)
            {
                Debug.WriteLine($"卸载服务失败: {ex.Message}");
                return false;
            }
        }

        /// <summary>
        /// 启动Windows服务
        /// </summary>
        public static bool StartService()
        {
            try
            {
                ServiceController controller = new ServiceController(ServiceName);
                if (controller.Status != ServiceControllerStatus.Running)
                {
                    controller.Start();
                    controller.WaitForStatus(ServiceControllerStatus.Running, TimeSpan.FromSeconds(10));
                }
                return controller.Status == ServiceControllerStatus.Running;
            }
            catch (Exception ex)
            {
                Debug.WriteLine($"启动服务失败: {ex.Message}");
                return false;
            }
        }

        /// <summary>
        /// 停止Windows服务
        /// </summary>
        public static bool StopService()
        {
            try
            {
                ServiceController controller = new ServiceController(ServiceName);
                if (controller.Status != ServiceControllerStatus.Stopped)
                {
                    controller.Stop();
                    controller.WaitForStatus(ServiceControllerStatus.Stopped, TimeSpan.FromSeconds(10));
                }
                return controller.Status == ServiceControllerStatus.Stopped;
            }
            catch (Exception ex)
            {
                Debug.WriteLine($"停止服务失败: {ex.Message}");
                return false;
            }
        }

        /// <summary>
        /// 代理服务宿主类，用于Topshelf服务集成
        /// </summary>
        public class ProxyServiceHost
        {
            private readonly ProxyManager _proxyManager;

            public ProxyServiceHost()
            {
                _proxyManager = ProxyManager.Instance;
            }

            /// <summary>
            /// 服务启动时调用
            /// </summary>
            public bool Start()
            {
                _proxyManager.StartAllProxies();
                return true;
            }

            /// <summary>
            /// 服务停止时调用
            /// </summary>
            public bool Stop()
            {
                _proxyManager.StopAllProxies();
                return true;
            }

            /// <summary>
            /// 配置并运行Topshelf服务
            /// </summary>
            public static void ConfigureService()
            {
                HostFactory.Run(x =>
                {
                    x.Service<ProxyServiceHost>(s =>
                    {
                        s.ConstructUsing(name => new ProxyServiceHost());
                        s.WhenStarted(tc => tc.Start());
                        s.WhenStopped(tc => tc.Stop());
                    });

                    x.RunAsLocalSystem();
                    x.SetServiceName(WindowsServiceManager.ServiceName);
                    x.SetDisplayName(WindowsServiceManager.ServiceDisplayName);
                    x.SetDescription(WindowsServiceManager.ServiceDescription);
                });
            }
        }
    }
}